package class02_异或运算.test;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;

public class Code03_KM {
    public static int test(int[] arr, int k,int m){
        HashMap<Integer,Integer> record = new HashMap();
        for (int i = 0; i < arr.length; i++) {
            if(record.containsKey (arr[i])){
                record.put(arr[i],record.get(arr[i])+1);
            }else {
                record.put(arr[i],1);
            }
        }
        for (Integer key : record.keySet()) {
            if(record.get(key) == k){
                return key;
            }
        }

        return -1;
    }

    public static int onlyKTimes(int[] arr,int k,int m){
        int[] onetimes = new int[32];
        for (int i = 0; i < arr.length; i++) {
            for (int i1 = 0; i1 < 32; i1++) {
                if(((arr[i] >> i1) & 1) != 0){
                    onetimes[i1]++;
                }
            }
        }
        int res = 0;
        for (int i = 0; i < onetimes.length; i++) {
            if(onetimes[i] != 0){
                if(onetimes[i]%m != 0){
                    if(onetimes[i]%m == k){
                        res |=  1 << i;
                    }
                }
            }
        }
        if (res == 0) {
            int count = 0;
            for (int num : arr) {
                if (num == 0) {
                    count++;
                }
            }
            if (count != k) {
                return -1;
            }
        }
        return res;
    }

    //range 数值的范围
    //maxKinds 最多有多少种数值
    public static int[] randomArray(int maxKinds, int range, int k, int m) {
        int ktimeNum = randomNumber(range);
        // 真命天子出现的次数
        int times = Math.random() < 0.5 ? k : ((int) (Math.random() * (m - 1)) + 1);
        // 2
        int numKinds = (int) (Math.random() * maxKinds) + 2;
        // k * 1 + (numKinds - 1) * m
        int[] arr = new int[times + (numKinds - 1) * m];
        int index = 0;
        for (; index < times; index++) {
            arr[index] = ktimeNum;
        }
        numKinds--;
        HashSet<Integer> set = new HashSet<>();
        set.add(ktimeNum);
        while (numKinds != 0) {
            int curNum = 0;
            do {
                curNum = randomNumber(range);
            } while (set.contains(curNum));
            set.add(curNum);
            numKinds--;
            for (int i = 0; i < m; i++) {
                arr[index++] = curNum;
            }
        }
        // arr 填好了
        for (int i = 0; i < arr.length; i++) {
            // i 位置的数，我想随机和j位置的数做交换
            int j = (int) (Math.random() * arr.length);// 0 ~ N-1
            int tmp = arr[i];
            arr[i] = arr[j];
            arr[j] = tmp;
        }
        return arr;
    }

    // [-range, +range]
    public static int randomNumber(int range) {
        return ((int) (Math.random() * range) + 1) - ((int) (Math.random() * range) + 1);
    }

    public static void main(String[] args) {
        int kinds = 5;
        int range = 30;
        int testTime = 100000;
        int max = 9;
        System.out.println("测试开始");
        for (int i = 0; i < testTime; i++) {
            int a = (int) (Math.random() * max) + 1; // a 1 ~ 9
            int b = (int) (Math.random() * max) + 1; // b 1 ~ 9
            int k = Math.min(a, b);
            int m = Math.max(a, b);
            // k < m
            if (k == m) {
                m++;
            }
            int[] arr = randomArray(kinds, range, k, m);
            int ans1 = test(arr, k, m);
            int ans2 = onlyKTimes(arr, k, m);
            if (ans1 != ans2) {
                System.out.println(ans1);
                System.out.println(ans2);
                System.out.println("出错了！");
            }
        }
        System.out.println("测试结束");

    }
}
